/*-----------------------------------------------------------------------
|                            FILE DESCRIPTION                           |
-----------------------------------------------------------------------*/
/*----------------------------------------------------------------------
  - File name     : TMT.c
  - Author        : zeweni
  - Update date   : 2020.06.26                  
  -	Copyright(c)  : 2020-2021 zeweni. All rights reserved.
-----------------------------------------------------------------------*/
/*------------------------------------------------------------------------
|                            COPYRIGHT NOTICE                            |
------------------------------------------------------------------------*/
/*
 * Copyright (C) 2021, zeweni (17870070675@163.com)

 * This file is part of task management time slice framework.
 * Abbreviated as TMT.
 
 * Task management time slice framework is free software: you can redist-
 * ribute it and/or modify it under the terms of the Apache-2.0 License.

 * Task management time slice framework is distributed in the hope that it 
 * will be useful,but WITHOUT ANY WARRANTY; without even the implied  
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 * Apache-2.0 License for more details.

 * You should have received a copy of the Apache-2.0 License.Task management 
 * time slice framework. If not, see <http://www.apache.org/licenses/>.
**/
/*-----------------------------------------------------------------------
|                               INCLUDES                                |
-----------------------------------------------------------------------*/
#include "TMT.h"
/*-----------------------------------------------------------------------
|                                 DATA                                  |
-----------------------------------------------------------------------*/

/**
 * @brief     最大任务数量宏，再封装一层。
 * @details   The maximum number of tasks is a macro, 
 *            and then one layer is encapsulated.
**/
#define  TASKS_MAX       TMT_TASK_NUM


/**
 * @brief   定义TMT相关操作函数结构体。
 * @details Define the structure of the TMT related operation functions.
**/
TMT_Type TMT;


/**
 * @brief   TMT的类，包含公共和私有两个属性。
 * @details Class of TMT, containing both public and private properties.
**/
static struct Class
{
	TMT_Type Public;  /*!< 公共部分，对外开放的属性，具体定义在头文件。*/
	
	struct Private   /*!< 私有部分，仅限本文件内调用。*/
	{
		struct
		{
			void (* Entry) (void); /*!< 任务函数入口指针。*/
			uint16_t TIMCount;     /*!< 任务调度时间计数器。*/
			uint16_t SetTime;      /*!< 任务设置的调度时间。*/
			uint8_t State;         /*!< 任务运行状态。*/
		}Comp[TASKS_MAX];
		
		uint8_t Num;   /*!< 已经创建的任务数量。*/
	}Private;
	
}Object;

/*-----------------------------------------------------------------------
|                               FUNCTION                                |
-----------------------------------------------------------------------*/

/**
 * @brief     TMT更新任务调度tick时间。
 * @details   TMT update task schedule tick time.
 * @param[in] None.
 * @return    None.
**/
static void TMT_Update_Tick_t(void)
{
	uint8_t i;
	for(i = 0; i< Object.Private.Num; i++)
    {
		 /* If time arrives */
        if(Object.Private.Comp[i].TIMCount > 0 )
        {
            Object.Private.Comp[i].TIMCount--;
        }
	}	
}

/**
 * @brief     TMT运行函数，是任务调度器。
 * @details   TMT runs the function, which is the task scheduler.
 * @param[in] None.
 * @return    None.
**/
static void TMT_Run_t(void)
{
	uint8_t index;
	for(index = 0; index < Object.Private.Num; index++)
	{
		 /* If time arrives */
		if(Object.Private.Comp[index].TIMCount == 0 && Object.Private.Comp[index].State != Task_Stop)
		{
			Object.Private.Comp[index].TIMCount = Object.Private.Comp[index].SetTime;
			
			/* 
				To prevent process conflict, 
				only one process can be executed in the same time period.
			*/
			if(Object.Private.Comp[index].Entry != (void*)(0) )
			{
				Object.Private.Comp[index].Entry();  /* Run task */
			}
		}
	}
}


/**
 * @brief     TMT创建一个任务函数。
 * @details   TMT creates a task function.
 * @param[in] entry 任务函数入口指针.
 *            A pointer function without formal parameters.
 * @param[in] setTime 任务调度的时间 task run time (ticks)
 * @return    [TMT_OK]创建成功.Create successfully.
 * @return    [TMT_NOK]创建失败.	Create failed.
**/	
static TMT_FunState_Type TMT_Create_t(void (*entry) (void),uint16_t setTime)
{	
    static uint8_t task_num = 0; /* Initialize to 0 */
	if(task_num < TASKS_MAX)
	{
		Object.Private.Comp[task_num].Entry = entry;
		Object.Private.Comp[task_num].SetTime = setTime;
		Object.Private.Comp[task_num].TIMCount = setTime;
		Object.Private.Comp[task_num].State = Task_Continue;
		task_num += 1;
		Object.Private.Num = task_num;
		return TMT_OK;
	}
	else
	{
		return TMT_NOK;	
	}		
}


/**
 * @brief     TMT删除一个任务函数。
 * @details   TMT creates a task function.
 * @param[in] entry 任务函数入口指针.
 *            A pointer function without formal parameters.
 * @return    [TMT_OK]删除成功.Delete successfully.
 * @return    [TMT_NOK]删除失败.	Delete failed.
**/	
static TMT_FunState_Type TMT_Delete_t(void (*entry) (void))
{	
    uint8_t index;
    if(Object.Private.Num > 0)
    {
        ENTER_TMT_CRI_AREA();
		
        for(index = 0; index < Object.Private.Num; index++)
        {
            if(Object.Private.Comp[index].Entry == entry)
            {
                    Object.Private.Num--;
                    Object.Private.Comp[index].Entry = Object.Private.Comp[Object.Private.Num].Entry;
                    Object.Private.Comp[index].SetTime = Object.Private.Comp[Object.Private.Num].SetTime;
                    Object.Private.Comp[index].TIMCount = Object.Private.Comp[Object.Private.Num].TIMCount;
                    Object.Private.Comp[index].State = Object.Private.Comp[Object.Private.Num].State;
                    EXTI_TMT_CRI_AREA();
                    return TMT_OK;
            }
        }
    }
    EXTI_TMT_CRI_AREA();
    return TMT_NOK;
}


/**
 * @brief     TMT控制一个任务运行状态函数。
 * @details   TMT controls a task running state function.
 * @param[in] entry 任务函数入口指针.
 *            A pointer function without formal parameters.
 * @param[in] state 任务运行状态.Task running status
 * @return    [TMT_OK]修改成功.The modification was successful.
 * @return    [TMT_NOK]修改失败.The modification was failed.
**/	
static TMT_FunState_Type TMT_RunCtrl_t(void (*entry)(void),TaskState_Type state)
{
	uint8_t index;
	for(index = 0; index<Object.Private.Num; index++)
	{
		if(Object.Private.Comp[index].Entry == entry)
		{
		    Object.Private.Comp[index].State = state;
			return TMT_OK;
		}
	}
	return TMT_NOK;
}


/**
 * @brief     TMT控制一个任务的调度时间函数。
 * @details   The TMT controls the scheduling time function of a task.
 * @param[in] *taskFunc (void) 任务函数入口指针.
 *            A pointer function without formal parameters.
 * @param[in] setTime 任务调度的时间 task run time (ticks)
 * @return    [TMT_OK]修改成功.The modification was successful.
 * @return    [TMT_NOK]修改失败.The modification was failed.
**/	
static TMT_FunState_Type TMT_TimeCtrl_t(void (*entry) (void),uint16_t setTime)
{	
	uint8_t index;
	for(index = 0; index< Object.Private.Num; index++)
	{
		if(Object.Private.Comp[index].Entry == entry)
		{
			Object.Private.Comp[index].TIMCount = setTime;
			Object.Private.Comp[index].SetTime = setTime;
			return TMT_OK;
		}
	}
	return TMT_NOK;
}


/**
 * @brief   TMT初始化函数，注册相关元素。
 * @details The TMT initializes the function 
 *          and registers the associated elements.
 * @param   None.
 * @return  None.
**/
void TMT_Init(void)
{
	Object.Public.Run = TMT_Run_t;
	Object.Public.Tick = TMT_Update_Tick_t;
	Object.Public.Create = TMT_Create_t;
	Object.Public.Delete = TMT_Delete_t;
	Object.Public.TimeCtrl = TMT_TimeCtrl_t;
	Object.Public.RunCtrl = TMT_RunCtrl_t;
	Object.Private.Num = 0;
	
	TMT = Object.Public;
}

/*-----------------------------------------------------------------------
|                   END OF FLIE.  (C) COPYRIGHT zeweni                  |
-----------------------------------------------------------------------*/


